class Snake {
  // 蛇的容器
  public element: HTMLElement;
  // 蛇头 #snake里面的第一个div
  public head: HTMLElement;
  // 蛇的身体,含蛇头，是一个集合
  public bodies: HTMLCollection;

  constructor() {
    this.element = document.getElementById("snake")!;
    this.head = document.querySelector("#snake > div") as HTMLElement;
    this.bodies = this.element.getElementsByTagName("div");
  }

  get X() {
    return this.head.offsetLeft;
  }

  get Y() {
    return this.head.offsetTop;
  }

  set X(value: number) {
    if (value === this.X) return;
    if (value < 0 || value > 290) {
      throw Error("蛇撞墙了");
    }
    if (
      this.bodies[1] &&
      (this.bodies[1] as HTMLElement).offsetLeft === value
    ) {
      console.log("水平方向发生掉头");
      // 发生掉头时，让蛇向反方向继续走
      if (value > this.X) {
        value = this.X - 10;
      } else {
        value = this.X + 10;
      }
    }
    this.moveBody()
    this.head.style.left = `${value}px`;
    this.checkHeadBody()
  }

  set Y(value: number) {
    if (value === this.Y) return;
    if (value < 0 || value > 290) {
      throw Error("蛇撞墙了");
    }
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
      console.log("垂直方向发生掉头");
      // 发生掉头时，让蛇向反方向继续走
      if (value > this.Y) {
        value = this.Y - 10;
      } else {
        value = this.Y + 10;
      }
    }
    this.moveBody()
    this.head.style.top = `${value}px`;
    this.checkHeadBody()
  }

  addBody() {
    this.element.insertAdjacentHTML("beforeend", "<div></div>");
  }

  moveBody() {
    for (let i = this.bodies.length - 1; i > 0; i--) {
      // 获取前边身体的位置
      let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
      let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

      // 将值设置到当前身体上
      (this.bodies[i] as HTMLElement).style.left = X + "px";
      (this.bodies[i] as HTMLElement).style.top = Y + "px";
    }
  }

  checkHeadBody() {
    for(let i = 1; i<this.bodies.length-1; i++) {
      const bd = this.bodies[i]  as HTMLElement
      if(bd.offsetLeft === this.X && bd.offsetHeight === this.Y) {
        throw Error("蛇撞到自己了");
      }
    }
  }
}

export default Snake;
